using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebControls;

namespace SPSolutions.Samples.PickerApp.WebControls
{
    /// <summary>
    /// Represent a context selector that has been edited to accept input from an entity editor
    /// </summary>
    public abstract class ContextSelectorEntityEditorAdapter<T> : ContextSelector<T>
    {
        /// <summary>
        /// Defien the picker dialog type
        /// </summary>
        public abstract Type PickerDialogType { get; }

        /// <summary>
        /// True if you want to use cookie initialization
        /// </summary>
        public bool UseCookieInitialization
        {
            get
            {
                if (ViewState["UseCookieInitialization"] == null)
                {
                    return true;
                }
                return (bool)ViewState["UseCookieInitialization"];
            }
            set { ViewState["UseCookieInitialization"] = value; }
        }

        /// <summary>
        /// Current cookie id
        /// </summary>
        internal static string CookieCurrentId
        {
            get
            {
                // Get the static facotry method
                PropertyInfo cookieCurrentIdProperty = typeof(ContextSelector<T>).GetProperty(
                    "CookieCurrentId",
                    BindingFlags.NonPublic | BindingFlags.Static);

                // Get available provider
                return (string) cookieCurrentIdProperty.GetValue(null, null);
            }
            set
            {
                // Get the static facotry method
                PropertyInfo cookieCurrentIdProperty = typeof(ContextSelector<T>).GetProperty(
                    "CookieCurrentId",
                    BindingFlags.NonPublic | BindingFlags.Static);

                // Get available provider
                cookieCurrentIdProperty.SetValue(null, value, null);
            }
        }
 
        /// <summary>
        /// Get navigate url
        /// </summary>
        protected override string NavigateUrl
        {
            get
            {
                return String.Format(
                    "/_layouts/picker.aspx?PickerDialogType={0}",
                    HttpUtility.UrlEncode(PickerDialogType.AssemblyQualifiedName));
            }
        }

        /// <summary>
        /// On control intialize
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
        }

        /// <summary>
        /// Define the pre-rending method
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            // Allow change
            if (AllowChange)
            {
                string scriptLiteralToEncode;
                string selectContextKey = "SelectContext_" + ID;
                string callbackKey = "CallbackWrapper_" + ID;

                // Set url
                scriptLiteralToEncode = (CurrentItem == null) ?
                    NavigateUrl :
                    string.Format("{0}&{1}={2}", NavigateUrl, Key, CurrentId);

                string selectContextScript = "<script language='javascript'>\r\n                        function " + selectContextKey + "(returnValue)\r\n                        {\r\n                            if (typeof(returnValue)!= 'undefined' && returnValue != '" + SPHttpUtility.EcmaScriptStringLiteralEncode(CurrentId) + "' ) \r\n                            {\r\n                                STSNavigate(StURLSetVar2(window.location.href, '" + SPHttpUtility.EcmaScriptStringLiteralEncode(Key) + "' , returnValue));\r\n                            }\r\n                        }\r\n                        </script>";
                Page.ClientScript.RegisterClientScriptBlock(typeof(ContextSelectorEntityEditorAdapter<T>), selectContextKey, selectContextScript);

                // Set script
                string callbackWrapperScript =
                        "<script language='javascript'>\r\n" +
                        "function " + callbackKey + "(xml)\r\n" +
                        "{\r\n" +
                                "var xmlDoc;\r\n" +
                                "if(xml==null)\r\n" +
                                    "return;\r\n" +

                                "if(document.implementation && document.implementation.createDocument)\r\n" +
                                "{\r\n" +
                                    "xmlDoc=(new DOMParser()).parseFromString(xml, \"text/xml\");\r\n" +
                                "}\r\n" +
                                "else\r\n" +
                                "{\r\n" +
                                    "xmlDoc=new ActiveXObject(\"Microsoft.XMLDOM\");\r\n" +
                                    "xmlDoc.async=false;\r\n" +
                                    "xmlDoc.loadXML(xml);\r\n" +
                                "}\r\n" +

                                "var entities=xmlDoc.documentElement;\r\n" +
                                "if(entities.childNodes.length == 0)\r\n" +
                                    "return;\r\n" +
                                "var entity = entities.childNodes[0];\r\n" +
                                selectContextKey + "(entity.getAttribute(\"Key\"));\r\n" +
                        "}\r\n" +
                        "</script>";
                Page.ClientScript.RegisterClientScriptBlock(typeof(ContextSelectorEntityEditorAdapter<T>), callbackKey, callbackWrapperScript);
                
                // Set picker open dialog command
                string valueToEncode = string.Format(CultureInfo.InvariantCulture, "commonShowModalDialog('{0}','resizable: yes; status: no; scroll: no; help: no; center: yes; dialogWidth : {1}pt; dialogHeight : {2}pt;',{3});", new object[] { SPHttpUtility.EcmaScriptStringLiteralEncode(scriptLiteralToEncode), DialogWidth, DialogHeight, SPHttpUtility.EcmaScriptStringLiteralEncode(callbackKey) });
                ChangeItem.ClientOnClickScript = SPHttpUtility.NoEncode(valueToEncode);
                PickerDialog.RegisterPickerReturnValueHiddenFields(Page);
            }
        }

        /// <summary>
        /// Load control
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            //base.OnLoad(e);
            if (!Page.IsPostBack && ((CurrentItem == null) || CurrentItem.Equals(default(T))))
            {
                string idFromQueryString = IdFromQueryString;
                if (idFromQueryString == null)
                {
                    if (string.IsNullOrEmpty(ClearSelectionText))
                    {
                        if (UseCookieInitialization)
                        {
                            CurrentId = CookieCurrentId;
                        }
                        else if ((CurrentItem == null) || CurrentItem.Equals(default(T)))
                        {
                            CurrentId = DefaultSelectionId();
                        }
                    }
                }
                else
                {
                    CurrentId = idFromQueryString;
                }
            }
        }

    }
}
